

template<int M,int N>
void Matrix<M,N>::loadIdentity (){
	for ( int i = 0; i < M; ++i ){	
		for ( int j = 0; j < N; ++j ){
			if ( i == j )	{ ((*this))(i,j) = 1.0; }
			else			{ ((*this))(i,j) = 0.0; }
		}
	}
}

template<int M,int N>
void Matrix<M,N>::translate (float dx, float dy, float dz)
{
	float trans[4][4] = {	{ 1.0 , 0.0 , 0.0 , dx	},
							{ 0.0 , 1.0 , 0.0 , dy	},
							{ 0.0 , 0.0 , 1.0 , dz	},
							{ 0.0 , 0.0 , 0.0 , 1.0			}	};
	
	mult( (*this),		(*this),trans );
}

template<int M,int N>
void Matrix<M,N>::translate (const Vertex3f& v)
{
	float trans[4][4] = {	{ 1.0 , 0.0 , 0.0 , v.x()	},
							{ 0.0 , 1.0 , 0.0 , v.y()	},
							{ 0.0 , 0.0 , 1.0 , v.z()	},
							{ 0.0 , 0.0 , 0.0 , 1.0		}	};
	
	mult( (*this),		(*this),trans );
}

template<int M,int N>
void Matrix<M,N>::scale (float sx, float sy, float sz)
{
	float scale[4][4] = {	{ sx , 0.0 , 0.0 , 0.0	},
							{ 0.0 , sy , 0.0 , 0.0	},
							{ 0.0 , 0.0 , sz , 0.0	},
							{ 0.0 , 0.0 , 0.0 , 1.0	}	};
	
	mult( (*this),		(*this),scale );
}

template<int M,int N>
void Matrix<M,N>::rotate_x (float degrees) {
	float radians = (degrees / 360.0) * 2 * 3.14159;
	float rotate[4][4] = {	{ 1.0 , 0.0 , 0.0 , 0.0	},
							{ 0.0 , cos(radians) , -1.0 * sin(radians) , 0.0	},
							{ 0.0 , sin(radians) , cos(radians) , 0.0	},
							{ 0.0 , 0.0 , 0.0 , 1.0	}	};
							
	mult( (*this),		(*this),rotate );
}

template<int M,int N>
void Matrix<M,N>::rotate_y (float degrees) {
	float radians = (degrees / 360.0) * 2 * 3.14159;
	float rotate[4][4] = {	{ cos(radians) , 0.0 , sin(radians) , 0.0	},
							{ 0.0 , 1.0 , 0.0 , 0.0	},
							{ -1.0 * sin(radians) , 0.0 , cos(radians) , 0.0	},
							{ 0.0 , 0.0 , 0.0 , 1.0	}	};
	
	mult( (*this),		(*this),rotate );
}

template<int M,int N>
void Matrix<M,N>::rotate_z (float degrees) {
	float radians = (degrees / 360.0) * 2 * 3.14159;
	float rotate[4][4] = {	{ cos(radians) , -1.0 * sin(radians) , 0.0 , 0.0	},
							{ sin(radians) , cos(radians) , 0.0 , 0.0	},
							{ 0.0 , 0.0, 1.0 , 0.0	},
							{ 0.0 , 0.0 , 0.0 , 1.0	}	};
	
	mult( (*this),		(*this),rotate );
}

template<int M,int N>
void Matrix<M,N>::negate_x () {
	
	float neg[4][4] = {	{ -1.0 , 0.0 , 0.0 ,  0.0	},
							{ 0.0 , 1.0 , 0.0 , 0.0		},
							{ 0.0 , 0.0 , 1.0 , 0.0		},
							{ 0.0 , 0.0 , 0.0 ,  1.0	}	};
	mult((*this),	(*this),neg);
}

template<int M,int N>
void Matrix<M,N>::negate_y () {

	float neg[4][4] = {	{ 1.0 , 0.0 , 0.0 ,  0.0	},
							{ 0.0 , -1.0 , 0.0 ,  0.0	},
							{ 0.0 , 0.0 , 1.0 , 0.0	},
							{ 0.0 , 0.0 , 0.0 ,  1.0	}	};
	mult((*this),	(*this),neg);

}

template<int M,int N>
void Matrix<M,N>::negate_z () {
	float neg[4][4] = {	{ 1.0 , 0.0 , 0.0 ,  0.0	},
							{ 0.0 , 1.0 , 0.0 , 0.0	},
							{ 0.0 , 0.0 , -1.0 , 0.0		},
							{ 0.0 , 0.0 , 0.0 ,  1.0	}	};
	mult((*this),	(*this),neg);
}